home *** CD-ROM | disk | FTP | other *** search
/ Aminet 24 / Aminet 24 (1998)(GTI - Schatztruhe)[!][Apr 1998].iso / Aminet / comm / mail / Mutt089src.lha / Mutt-0.89i-AMIGA / src / complete.c < prev    next >
C/C++ Source or Header  |  1998-01-28  |  4KB  |  167 lines

  1. /*
  2.  * Copyright (C) 1996-8 Michael R. Elkins <me@cs.hmc.edu>
  3.  * 
  4.  *     This program is free software; you can redistribute it and/or modify
  5.  *     it under the terms of the GNU General Public License as published by
  6.  *     the Free Software Foundation; either version 2 of the License, or
  7.  *     (at your option) any later version.
  8.  * 
  9.  *     This program is distributed in the hope that it will be useful,
  10.  *     but WITHOUT ANY WARRANTY; without even the implied warranty of
  11.  *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12.  *     GNU General Public License for more details.
  13.  * 
  14.  *     You should have received a copy of the GNU General Public License
  15.  *     along with this program; if not, write to the Free Software
  16.  *     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  17.  */ 
  18.  
  19. #include "mutt.h"
  20.  
  21. #include <dirent.h>
  22. #include <string.h>
  23. #include <sys/types.h>
  24. #include <sys/stat.h>
  25. #include <errno.h>
  26.  
  27. /* given a partial pathname, this routine fills in as much of the rest of the
  28.  * path as is unique.
  29.  *
  30.  * return 0 if ok, -1 if no matches
  31.  */
  32. int mutt_complete (char *s)
  33. {
  34.   char *p;
  35.   DIR *dirp;
  36.   struct dirent *de;
  37.   int i ,init=0;
  38.   size_t len;
  39.   char dirpart[_POSIX_PATH_MAX], exp_dirpart[_POSIX_PATH_MAX];
  40.   char filepart[_POSIX_PATH_MAX];
  41.   
  42.   if (*s == '=' || *s == '+')
  43.   {
  44.     dirpart[0] = *s;
  45.     dirpart[1] = 0;
  46.     strfcpy (exp_dirpart, Maildir, sizeof (exp_dirpart));
  47.     if ((p = strrchr (s, '/')))
  48.     {
  49.       *p++ = 0;
  50.       sprintf (exp_dirpart + strlen (exp_dirpart), "/%s", s+1);
  51.       sprintf (dirpart + strlen (dirpart), "%s/", s+1);
  52.       strfcpy (filepart, p, sizeof (filepart));
  53.     }
  54.     else
  55.       strfcpy (filepart, s + 1, sizeof (filepart));
  56.     dirp = opendir (exp_dirpart);
  57.   }
  58.   else
  59.   {
  60.     if ((p = strrchr (s, '/')))
  61.     {
  62.       if (p == s) /* absolute path */
  63.       {
  64.     p = s + 1;
  65.     strfcpy (dirpart, "/", sizeof (dirpart));
  66.     exp_dirpart[0] = 0;
  67.     strfcpy (filepart, p, sizeof (filepart));
  68.     dirp = opendir (dirpart);
  69.       }
  70.       else
  71.       {
  72.     *p = 0;
  73.     len = (size_t)(p - s);
  74.     strncpy (dirpart, s, len);
  75.     dirpart[len]=0;
  76.     p++;
  77.     strfcpy (filepart, p, sizeof (filepart));
  78.     strfcpy (exp_dirpart, dirpart, sizeof (exp_dirpart));
  79.     mutt_expand_path (exp_dirpart, sizeof (exp_dirpart));
  80.     dirp = opendir (exp_dirpart);
  81.       }
  82.     }
  83.     else
  84.     {
  85.       /* no directory name, so assume current directory. */
  86.       dirpart[0] = 0;
  87.       strfcpy (filepart, s, sizeof (filepart));
  88.       dirp = opendir (".");
  89.     }
  90.   }
  91.  
  92.   if (dirp == NULL)
  93.   {
  94.     dprint (1, (debugfile, "mutt_complete(): %s: %s (errno %d).\n", exp_dirpart, strerror (errno), errno));
  95.     return (-1);
  96.   }
  97.  
  98.   /*
  99.    * special case to handle when there is no filepart yet.  find the first
  100.    * file/directory which is not ``.'' or ``..''
  101.    */
  102.   if ((len = strlen (filepart)) == 0)
  103.   {
  104.     while ((de = readdir (dirp)) != NULL)
  105.     {
  106.       if (strcmp (".", de->d_name) != 0 && strcmp ("..", de->d_name) != 0)
  107.       {
  108.     strfcpy (filepart, de->d_name, sizeof (filepart));
  109.     init++;
  110.     break;
  111.       }
  112.     }
  113.   }
  114.  
  115.   while ((de = readdir (dirp)) != NULL)
  116.   {
  117.     if (strncmp (de->d_name, filepart, len) == 0)
  118.     {
  119.       if (init)
  120.       {
  121.     for (i=0; filepart[i] && de->d_name[i]; i++)
  122.     {
  123.       if (filepart[i] != de->d_name[i])
  124.       {
  125.         filepart[i] = 0;
  126.         break;
  127.       }
  128.     }
  129.     filepart[i] = 0;
  130.       }
  131.       else
  132.       {
  133.     char buf[_POSIX_PATH_MAX];
  134.     struct stat st;
  135.  
  136.     strfcpy (filepart, de->d_name, sizeof(filepart));
  137.  
  138.     /* check to see if it is a directory */
  139.     if (dirpart[0])
  140.     {
  141.       strfcpy (buf, exp_dirpart, sizeof (buf));
  142.       strcat (buf, "/");
  143.     }
  144.     else
  145.       buf[0] = 0;
  146.     strcat (buf, filepart);
  147.     if (stat (buf, &st) != -1 && (st.st_mode & S_IFDIR))
  148.       strcat (filepart, "/");
  149.     init = 1;
  150.       }
  151.     }
  152.   }
  153.   closedir (dirp);
  154.  
  155.   if (dirpart[0])
  156.   {
  157.     strcpy (s, dirpart);
  158.     if (strcmp ("/", dirpart) != 0 && dirpart[0] != '=' && dirpart[0] != '+')
  159.       strcat (s, "/");
  160.     strcat (s, filepart);
  161.   }
  162.   else
  163.     strcpy (s, filepart);
  164.  
  165.   return (init ? 0 : -1);
  166. }
  167.